談到單一責任的時候,有一種常常被忽略的責任就是參數檢查跟消毒(Sanitizer)
一般來說這種東西都會寫成像下面這樣
class TaskListA(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('page', type=int, location='args', default=1)
parser.add_argument('size', type=int, location='args', default=15)
parser.add_argument('project_id', type=int, location='args', default=0)
params = parser.parse_args()
max_size = 150
status = 200
size = params['size']
page = params['page']
task_status = params['task_status']
project_id = params['project_id']
if page <= 0 or size <= 0 or size > max_size:
status = 400
這邊有個很大的問題,如果今天有十種TaskListB .... TaskListZ
那這段邏輯就會重寫十次,極度恐怖而且極度麻煩
這邊Demo在另外一個專案使用的 sanitizer
decorator.py
def sanitize_parameter(parameter_keys):
def decorator(func):
def wrapper(params):
params_content = []
for key in parameter_keys:
if key not in params:
raise ParameterNotExist(key)
value = params.get(key)
if key == 'ProjectId':
project_id = params.get(key)
project = mysql.get_project_by_id(project_id)
if project is None:
raise ProjectNotFound(project_id)
if key == 'DefaultMode':
if not hasattr(TAGGING_MODE, value):
raise InvalidDefaultMode(value)
params_content.append(value)
return func(*params_content)
return wrapper
return decorator
request.py
@http_request
@need_auth
@sanitize_parameter(['ProjectId', 'Keys'])
def import_folder_hits(project_id, keys):
pass
這樣就能讓變數檢查變成可複製,可重複使用的